#include "SessionPanel.h"

#include "SessionNotebook.h"

#include "MessengerPanel.h"
#include "FileTransferPanel.h"
//#include "MainFrame.h"

#include "SessionEditor.h"
#include "SessionViewer.h"

#include "MsnContact.h"
#include "MsnMessenger.h"
#include "MsnSession.h"
#include "MsnEvent.h"
#include "MsnMessage.h"

#include "UserConfig.h"

#include "SessionManager.h"

//#include "wx/generic/colrdlgg.h"

int ID_VIEW_TEXTCTRL = wxNewId();

BEGIN_EVENT_TABLE(SessionPanel, wxPanel)
    EVT_TEXT_URL(ID_VIEW_TEXTCTRL, SessionPanel::OnTextUrl)

    EVT_COMMAND(wxID_ANY, EVT_MSN_INSTANT_MESSAGE_RECEIVED, SessionPanel::OnInstantMessageReceived)
    //EVT_COMMAND(wxID_ANY, EVT_MSN_CONTROL_MESSAGE_RECEIVED, SessionPanel::OnControlMessageReceived)

	EVT_COMMAND(wxID_ANY, EVT_MSN_FILE_INVITE_SENT, SessionPanel::OnFileInviteSent)	
	EVT_COMMAND(wxID_ANY, EVT_MSN_FILE_INVITE_RECEIVED, SessionPanel::OnFileInviteReceived)	
	
	EVT_COMMAND(wxID_ANY, EVT_MSN_FILE_TRANSFER_STARTED, SessionPanel::OnFileTransferStarted)
	EVT_COMMAND(wxID_ANY, EVT_MSN_FILE_TRANSFER_DONE, SessionPanel::OnFileTransferDone)
	EVT_COMMAND(wxID_ANY, EVT_MSN_FILE_TRANSFER_FAILED, SessionPanel::OnFileTransferFailed)
	EVT_COMMAND(wxID_ANY, EVT_MSN_FILE_TRANSFER_CANCELLED, SessionPanel::OnFileTransferCancelled)

	EVT_FILE_TRANSFER(EVT_MSN_FILE_TRANSFER_UPDATED, SessionPanel::OnFileTransferUpdated)

END_EVENT_TABLE()

SessionPanel::SessionPanel(MessengerPanel* mp, MsnSession* ms) 
: wxPanel((wxWindow*)mp->sessionNotebook, wxID_ANY), messengerPanel(mp), session(ms)
{
    m_DefaultFont = wxFont(wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxNORMAL, wxNORMAL);
    greyStyle = wxTextAttr(*wxLIGHT_GREY, *wxWHITE, m_DefaultFont);
	messageStyle = wxTextAttr(messengerPanel->messenger->GetUserConfig()->GetMessageColor(), *wxWHITE, messengerPanel->messenger->GetUserConfig()->GetMessageFont());
    failStyle = wxTextAttr(*wxRED, *wxWHITE, wxFont(wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT,wxNORMAL, wxFONTWEIGHT_BOLD )); 

	infoStyle = wxTextAttr(*wxBLACK, *wxWHITE,m_DefaultFont);

    m_UrlStyle.SetTextColour(*wxBLUE);
    m_UrlStyle.SetFontUnderlined(true);

    wxSplitterWindow* splitter = new wxSplitterWindow(this, -1, wxDefaultPosition, wxSize(600,600), wxSP_LIVE_UPDATE );
	//splitter->SetBackgroundColour(*wxWHITE);
	splitter->SetSashGravity(1.0);
	splitter->SetSashSize(1);


	sessionEditor = new SessionEditor(splitter, this);


	ftSplitter = new wxSplitterWindow(splitter, -1, wxDefaultPosition, wxDefaultSize, wxSP_LIVE_UPDATE);
	//splitter->SetBackgroundColour(*wxWHITE);
	ftSplitter->SetSashGravity(1.0);
	ftSplitter->SetSashSize(2);
	ftSplitter->SetMinimumPaneSize(50);

	sessionViewer = new SessionViewer(ftSplitter);
	sessionViewer->sessionPanel = this;

	ftPanel = new FileTransferPanel(ftSplitter);
	ftPanel->Hide();

	//ftSplitter->SplitVertically(sessionViewer, ftPanel, -200);
	ftSplitter->Initialize(sessionViewer);
	
	splitter->SplitHorizontally(ftSplitter, sessionEditor, -50);
	splitter->SetMinimumPaneSize(50);

	wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
    sizer->Add(splitter, 1, wxEXPAND);
   
	this->SetSizer(sizer);
}

SessionPanel::~SessionPanel()
{

	if(messengerPanel->messenger->GetSessionManager()){
		messengerPanel->messenger->GetSessionManager()->CloseSession(session);
	}

	DEBUG(_T("~SessionPanel"));
}

void SessionPanel::UpdateUIText()
{
	ftPanel->UpdateUIText();
}


bool SessionPanel::IsForContact(const wxString& passport)
{
	return session->IsForContact(passport);
}


void SessionPanel::AttachSession(MsnSession* _session)
{
	wxDELETE(session);
	session = _session;
}

void SessionPanel::OnContactStatusChanged(MsnContact* contact)
{
	if(contact->IsOffLine()){
		session->Close();
		sessionEditor->SetEditable(false);
	}else{
		sessionEditor->SetEditable(true);
	}
}

void SessionPanel::EnableChatCtrl(bool b)
{
/*
	chatPanel->textCtrl->SetEditable(b);

	if(b)
		chatPanel->textCtrl->SetBackgroundColour(*wxWHITE);
	else
		chatPanel->textCtrl->SetBackgroundColour(*wxLIGHT_GREY);
*/
}

void SessionPanel::OnContextMenu(wxContextMenuEvent& event)
{
	DEBUG(_T("OnContextMenu"));
}

void SessionPanel::ShowFileTransferPanel(bool b)
{
	int sashPos = ftSplitter->GetSashPosition();

	if(sashPos == 0){
		sashPos = -200;
	}

	if(b){
		ftSplitter->SplitVertically(sessionViewer, ftPanel, -200);
	}else{
		ftSplitter->Unsplit(ftPanel);
	}
}


void SessionPanel::AppendInstantMessage(const wxString& passport, const wxString& content, const wxFont& font, const wxColour& color)
{
   wxString userName = session->GetMessenger()->GetDisplayName(passport);

    sessionViewer->SetInsertionPointEnd();

    if(sessionViewer->GetInsertionPoint()>0)
        sessionViewer->Newline();

    sessionViewer->SetDefaultStyle(greyStyle);

	if(session->GetMessenger()->GetUserConfig()->GetShowTimeStamp()){
		wxString time = wxDateTime::Now().Format(_T("%Y-%m-%d %H:%M:%S"));
		sessionViewer->WriteText(_T("[")+time+_T("]"));
	}

	sessionViewer->WriteText(_T(" ") + userName + _T(" ") + _("say") + _T(": "));

    if(session->GetMessenger()->GetUserConfig()->GetShowNewLine()){
        sessionViewer->WriteText( _T("\n"));
    }

	sessionViewer->WriteText(_T(" "));

    wxTextAttr attr = wxTextAttr(color, *wxWHITE, font);
    sessionViewer->SetDefaultStyle(attr);

 //   sessionViewer->SetDefaultStyle(m_MessageStyle);

    sessionViewer->WriteText(content);
    sessionViewer->ShowPosition(sessionViewer->GetLastPosition());	
}

void SessionPanel::AppendInstantMessage(const wxString& passport, const wxString& content)
{
	wxFont font = messengerPanel->messenger->GetUserConfig()->GetMessageFont();
	wxColour color = messengerPanel->messenger->GetUserConfig()->GetMessageColor();

	AppendInstantMessage(passport, content,font, color);
}

void SessionPanel::AppendInstantMessageFailed(const wxString& content)
{
    sessionViewer->SetInsertionPointEnd();

    if(sessionViewer->GetInsertionPoint()>0)
        sessionViewer->Newline();

    sessionViewer->SetDefaultStyle(failStyle);
	
	sessionViewer->Newline();
	sessionViewer->WriteText(_("Below message can not be sent out successfully"));
	sessionViewer->Newline();
    sessionViewer->WriteText(content);
	sessionViewer->Newline();

    sessionViewer->ShowPosition(sessionViewer->GetLastPosition());
}

void SessionPanel::AppendFileInviteSent(FileTransferEntry* item)
{
	wxString contactName = session->GetMessenger()->GetDisplayName(session->GetContact(0));

	wxString info = _(" You are sending below file to ");

	info << contactName << _T("\r\n");

	info << _T("  ") << item->GetFileName();

    AppendFileTransferText(info);
}

void SessionPanel::AppendFileInviteReceived(FileTransferEntry* item)
{
	wxString info = session->GetMessenger()->GetDisplayName(session->GetContact(0));
		
	info << _(" is sending below file to you") <<_T("\r\n");
	info << _T("  ") << item->GetFileName();

	int fileSize = item->GetFileSize();
	info << _T(" (") << NumberUtil::B2KB(fileSize) << _T(" KB)");

	AppendFileTransferText(info);
}

void SessionPanel::AppendFileTransferFinished(FileTransferEntry* item)
{
	wxString info = _("Below file transfering is finished");
	info << _T("\r\n  ") << item->GetFileName();

	AppendFileTransferText(info);
}

void SessionPanel::AppendFileTransferFailed(FileTransferEntry* item)
{
	wxString info = _("Below file transfering is failed");
	info << _T("\r\n  ") << item->GetFileName();

	AppendFileTransferText(info);
}

void SessionPanel::AppendFileTransferText(const wxString& info)
{
   sessionViewer->SetInsertionPointEnd();

    if(sessionViewer->GetInsertionPoint()>0)
        sessionViewer->Newline();

	sessionViewer->SetDefaultStyle(infoStyle);
	sessionViewer->WriteText(info);
    sessionViewer->Newline();

    sessionViewer->ShowPosition(sessionViewer->GetLastPosition());	
}


void SessionPanel::OnTextUrl(wxTextUrlEvent& event)
{
    wxString link = event.GetString();

    wxString action = link.BeforeFirst(':');
    wxString cookie = link.AfterFirst(':');

}

void SessionPanel::AppendURL(const wxString& urlText, const wxString& urlLink)
{
    sessionViewer->BeginStyle(m_UrlStyle);
    sessionViewer->BeginURL(urlLink);
    sessionViewer->WriteText(urlText);
    sessionViewer->EndURL();
    sessionViewer->EndStyle();

    sessionViewer->WriteText(wxT(" "));
}

void SessionPanel::OnInstantMessageReceived(wxCommandEvent& event)
{
	DEBUG(_T("instant message received event"));

	InstantMessageItem* item = (InstantMessageItem*) event.GetClientData();

	AppendInstantMessage(item->contact, item->content, item->font, item->color);

	delete item;

	//if not the current session panel, change the icon
	if(this != messengerPanel->sessionNotebook->GetCurrentPage()){
		messengerPanel->sessionNotebook->SetPageImage(
			messengerPanel->sessionNotebook->GetPageIndex(this), ICON_CONTACT_NEWMSG
		);
	}

	SetNewMessage(true);
}

void SessionPanel::OnFileInviteSent(wxCommandEvent& event)
{
	DEBUG(_T("file invite sent event"));

	FileTransferEntry* item = (FileTransferEntry*) event.GetClientData();

	AppendFileInviteSent(item);

	ftPanel->AddFileTransfer(item);

	this->ShowFileTransferPanel(true);
}

void SessionPanel::OnFileInviteReceived(wxCommandEvent& event)
{
	DEBUG(_T("file invite received event"));

	FileTransferEntry* item = (FileTransferEntry*) event.GetClientData();	

	ftPanel->AddFileTransfer(item);

	AppendFileInviteReceived(item);

	this->ShowFileTransferPanel(true);

	wxGetApp().RequestUserAttention();
}


void SessionPanel::OnFileTransferStarted(wxCommandEvent& event)
{
	DEBUG(_T("file transfer started event"));

	wxString cookie = event.GetString();
	
	//FileTransferConnection* conn = (FileTransferConnection*)event.GetClientData();

	ftPanel->OnTransferStarted(cookie);	
}

void SessionPanel::OnFileTransferUpdated(FileTransferEvent& event)
{
	DEBUG(_T("file transfer updated event"));

	wxString cookie = event.GetCookie();

	ftPanel->OnTransferUpdated(cookie, event.GetTransferSize(), event.GetTransferSpeed());
}

void SessionPanel::OnFileTransferDone(wxCommandEvent& event)
{
	DEBUG(_T("file transfer done event"));

	wxString cookie = event.GetString();
	FileTransferEntry* item = (FileTransferEntry*)event.GetClientData();
	AppendFileTransferFinished(item);
	ftPanel->OnTransferDone(cookie);

	this->ShowFileTransferPanel(true);

	wxGetApp().RequestUserAttention();
}

void SessionPanel::OnFileTransferFailed(wxCommandEvent& event)
{
	DEBUG(_T("file transfer failed event"));

	wxString cookie = event.GetString();
	FileTransferEntry* item = (FileTransferEntry*)event.GetClientData();
	AppendFileTransferFailed(item);
	ftPanel->OnTransferFailed(cookie);

	this->ShowFileTransferPanel(true);

	wxGetApp().RequestUserAttention();
}

void SessionPanel::OnFileTransferCancelled(wxCommandEvent& event)
{
	DEBUG(_T("file transfer cancelled event"));

	wxString cookie = event.GetString();
	FileTransferEntry* item = (FileTransferEntry*)event.GetClientData();
	ftPanel->OnTransferCancelled(cookie);
	AppendFileTransferFailed(item);

	this->ShowFileTransferPanel(true);

	wxGetApp().RequestUserAttention();

}

